<?php

namespace app\commission;

use app\controllers\QueueData;
use app\models\order\Order;
use app\models\order\OrderItem;
use app\models\product\Product;
use app\models\product\ProductAreaList;
use app\models\Queue;
use app\models\SetProductCommission;
use app\models\SetUserUp;
use app\models\user\User;
use app\models\user\UserAccount;
use app\models\user\UserAddress;
use app\models\user\UserCommission;
use app\models\user\UserLevel;
use app\models\UserBalance;
use app\services\Chain;
use yii\helpers\ArrayHelper;

/**
 * 返佣
 *
 * Class ReturnCommission
 * @package app\commission
 */
class CommissionNew
{
    protected $user;
    protected $order;
    protected $set;

    protected $items;

    public function __construct(Order $order, $is_performance = false)
    {
        $this->order = $order;
        $this->user = User::findOne(['id' => $order->user_id]);

        $this->set = SetUserUp::getLastOne();

        // item list
        $this->items = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->all();

        $first_order_item = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->orderBy(['id' => SORT_ASC])
            ->limit(1)
            ->one();
        $product_id = $first_order_item->product_id;


        if (!$is_performance) {
            // 报单
            if (ProductAreaList::checkInArea($product_id, Product::$areaMap['REPORT'])) {

                // 总经销
                foreach ($this->items as $item) {
                    $product = Product::findOne(['id' => $item['product_id']]);

                    if ($product->price >= $this->set->vip3_price) {

                        $r = Chain::getReferrer($this->user->id, true);
                        if ($r && $r->level > 0) {

                            // 等级
                            if ($this->user->level < UserLevel::$keys['vip3']) {
                                $this->user->level = UserLevel::$keys['vip3'];
                                $this->user->save();
                            }
                            $this->saveCommission($r->id, $this->order->user_id, $this->order->id, $this->set->vip3_recommend, 88, '推荐总经销');

                            $r2 = Chain::getReferrer($r->id, true);
                            if ($r2) {
                                $this->saveCommission($r->id, $this->order->user_id, $this->order->id, $this->set->vip3_recommend_2, 89, '间推总经销');
                            }
                        }

                    } else {


                        $this->report();

                        $this->profit();
                        $this->area();
                        $this->performance();

                    }
                }

                // 可以不用记录了
                $this->user->repeat = 1;
                $this->user->save();


            }

            // 复购
            if (ProductAreaList::checkInArea($product_id, Product::$areaMap['REPEAT'])) {
                $this->repeat();

                $this->diff();

                $this->profit();
                $this->area();
                $this->performance();
            }
        }

    }

    public function performance()
    {
        // 队列老出问题,
        // 只能用mysql + crontab
        $queue = new Queue();
        $queue->order_id = $this->order->id;
        $queue->save();
    }

    public function receive_performance()
    {
        set_time_limit(60 * 60 * 24);

        // 由于队列可能中断,
        // 如果这笔订单已经返了, 就不操作了
        $is = UserCommission::find()
            ->where(['order_id' => $this->order->id])
            ->andWhere(['award_type' => 41])
            ->one();
        if ($is) {
            return;
        }

        $type = 41;
        $name = '绩效奖';

        $data = new QueueData();
        $list = $data->getList($this->order->user_id);

        foreach ($list as $item) {

            if ($item['commission'] <= 0) {
                continue;
            }

            $this->saveCommission($item['id'], $this->order->user_id, $this->order->id, $item['commission'], $type, $name);
            echo '佣金: ', $item['id'], ' , 金额: ', $item['commission'], "\n";

            // income
            $this->_income($item['id'], $item['commission'], '(绩效)');
        }

    }

    // 保存佣金
    protected function saveCommission($user_id, $fans_id, $order_id, $balance, $type, $name)
    {
        if ($balance > 0) {
            $model = new UserCommission();
            $model->user_id = $user_id;
            $model->fans_id = $fans_id;
            $model->order_id = $order_id;
            $model->balance = $balance;
            $model->status = 1;
            $model->award_name = $name;
            $model->award_type = $type;
            $model->save();

            $account = UserAccount::findOne(['user_id' => $user_id]);
            if ($account) {

                // balance logs
                UserBalance::addLog($user_id,
                    $account->balance, $balance, $account->balance + $balance, '返佣', $this->order->id);


                $account->balance += $balance;
                $account->save();
            }
        }
    }

    public function report()
    {
        $award = [
            [21, '销售提成'],
            [22, '裂变奖'],

            // [23, '平级奖'],
        ];

        // 根据order_item来
        foreach ($this->items as $item) {
            $product = Product::findOne(['id' => $item['product_id']]);

             if ($product->price == $this->set->vip1) {

                $referrer = Chain::getReferrer($this->user->id, true);
                if ($referrer) {

                    // vip1
                    if ($referrer->level == UserLevel::$keys['vip1']) {
                        $commission = $this->set->vip1_recommend;

                        $commission *= $item['quantity'];
                        $this->saveCommission($referrer->id, $this->order->user_id, $this->order->id, $commission, $award[0][0], $award[0][1]);

                        // second
                        $the_referrer = $this->getIndirect($referrer->id);
                        if ($the_referrer) {
                            $commission = $this->set->vip2_recommend - $this->set->vip1_recommend;

                            $commission *= $item['quantity'];
                            $this->saveCommission($the_referrer['id'], $this->order->user_id, $this->order->id, $commission, $award[1][0], $award[1][1]);

                            // equal
                            $this->_equal($the_referrer, $item['quantity']);
                        }
                    }


                    // vip2
                    // if ($referrer->level == UserLevel::$keys['vip2']) {
                    if ($referrer->level == UserLevel::$keys['vip2'] || $referrer->level == UserLevel::$keys['vip3']) {
                        $commission = $this->set->vip2_recommend;

                        $commission *= $item['quantity'];
                        $this->saveCommission($referrer->id, $this->order->user_id, $this->order->id, $commission, $award[0][0], $award[0][1]);

                        // equal
                        $this->_equal($referrer, $item['quantity']);
                    }

                }

            }
        }
    }

    private function _equal($the_referrer, $quantity, $is_repeat = false)
    {
        $type = 23;
        $name = '平级奖';

        if ($is_repeat) {
            $type = 24;
            $name = '平级奖';
        }

        $with_referrer =  Chain::getReferrerChainOne($the_referrer->id, [
            UserLevel::$keys['vip2'],
        ]);
        if ($with_referrer) {

            // equal 1
            $commission = $this->set->equal_1 * $quantity;
            $this->saveCommission($with_referrer['id'], $this->order->user_id, $this->order->id, $commission, $type, $name);

            // equal 2
            $with_referrer2 =  Chain::getReferrerChainOne($with_referrer['id'], [
                UserLevel::$keys['vip2'],
            ]);
            if ($with_referrer2) {
                $commission = $this->set->equal_2 * $quantity;
                $this->saveCommission($with_referrer2['id'], $this->order->user_id, $this->order->id, $commission, $type, $name);
            }
        }
    }

    public function profit()
    {
        $ids = Order::find()
            ->where(['DATE_FORMAT(create_time, "%Y-%m")' => date('Y-m')])
            ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
            ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
            ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
            ->select(['user_id'])
            ->column();
        $ids = array_unique($ids);

        // in team
        // $chain = Chain::getReferrerChain($this->order->user_id);
        // $team = ArrayHelper::getColumn($chain, 'id');
        // $team = array_merge([$this->order->user_id], $team);

        // 交集 (本月购买, 链)
        // $in = array_intersect($ids, $team);

        // var_dump($ids, $team, $in);exit;

        $users = User::find()
            ->where(['level' => UserLevel::$keys['vip3']])
            // ->andWhere(['id' => $ids])
            // ->andWhere(['id' => $in])
            ->andWhere(['id' => $ids])
            ->all();
        $count = count($users);

        // var_dump($users);exit;


        $type = 12;
        $name = '分红';
        if ($count > 0) {

            foreach ($users as $user) {
                $amount = $this->set->profit / $count;
                $amount = $amount * $this->order->total_quantity;
                $this->saveCommission($user->id, $this->order->user_id, $this->order->id, $amount, $type, $name);

                // income
                if ($user->level == UserLevel::$keys['vip3']) {
                    $this->_income($user->id, $amount, '(分红)');
                }
            }
        }
    }

    public function area()
    {
        $address = UserAddress::find()
            ->where(['id' => $this->order->user_address])
            ->one();

        if ($address->area_id > 0) {
            $svip1 = User::find()
                ->where(['address_up' => $address->area_id])
                ->orderBy(['update_time' => SORT_DESC])
                ->one();
            if ($svip1) {
                $amount = $this->set->area;
                $amount = $amount * $this->order->total_quantity;
                $this->_area($svip1->id, $amount);

                // income
                if ($svip1->level == UserLevel::$keys['vip3']) {
                    $this->_income($svip1->id, $amount, '(地区)');
                }
            }
        }

        $svip2 = User::find()
            ->where(['address_up' => $address->city_id])
            ->orderBy(['update_time' => SORT_DESC])
            ->one();
        if ($svip2) {
            $amount = $this->set->city;
            $amount = $amount * $this->order->total_quantity;
            $this->_area($svip2->id, $amount);

            // income
            if ($svip2->level == UserLevel::$keys['vip3']) {
                $this->_income($svip2->id, $amount, '(地区)');
            }
        }

        $svip3 = User::find()
            ->where(['address_up' => $address->province_id])
            ->orderBy(['update_time' => SORT_DESC])
            ->one();
        if ($svip3) {
            $amount = $this->set->province;
            $amount = $amount * $this->order->total_quantity;
            $this->_area($svip3->id, $amount);

            // income
            if ($svip3->level == UserLevel::$keys['vip3']) {
                $this->_income($svip3->id, $amount, '(地区)');
            }
        }
    }

    private function _area($user_id, $amount)
    {
        $type = 11;
        $name = '区域奖';

        $this->saveCommission($user_id, $this->order->user_id, $this->order->id, $amount, $type, $name);
    }

    public function repeat()
    {
        $award = [
            [21, '销售提成'],
            [22, '裂变奖'],

            // [23, '平级奖'],
        ];

        // 根据order_item来
        foreach ($this->items as $item) {
            $product = Product::findOne(['id' => $item['product_id']]);
            if ($product->price == $this->set->vip1) {

                $referrer = Chain::getReferrer($this->user->id, true);
                if ($referrer) {

                    // vip1
                    if ($referrer->level == UserLevel::$keys['vip1']) {
                        $commission = $this->set->repeat_vip1_recommend;

                        $commission *= $item['quantity'];
                        $this->saveCommission($referrer->id, $this->order->user_id, $this->order->id, $commission, $award[0][0], $award[0][1]);

                        // second
                        $the_referrer = $this->getIndirect($referrer->id);
                        if ($the_referrer) {
                            $commission = $this->set->repeat_vip2_second;

                            $commission *= $item['quantity'];
                            $this->saveCommission($the_referrer['id'], $this->order->user_id, $this->order->id, $commission, $award[1][0], $award[1][1]);

                            // equal
                            $this->_equal($the_referrer, $item['quantity']);
                        }
                    }


                    // vip2
                    // if ($referrer->level == UserLevel::$keys['vip2']) {
                    if ($referrer->level == UserLevel::$keys['vip2'] || $referrer->level == UserLevel::$keys['vip3']) {
                        $commission = $this->set->repeat_vip1_recommend + $this->set->repeat_vip2_second;

                        $commission *= $item['quantity'];
                        $this->saveCommission($referrer->id, $this->order->user_id, $this->order->id, $commission, $award[0][0], $award[0][1]);

                        // equal
                        $this->_equal($referrer, $item['quantity']);
                    }

                    // $commission = $this->set->repeat_vip1_recommend;
                    //
                    // $commission *= $item['quantity'];
                    // $this->saveCommission($referrer->id, $this->order->user_id, $this->order->id, $commission, $award[0][0], $award[0][1]);
                    //
                    // // second
                    // $second =  Chain::getReferrerChainOne($referrer->id, [
                    //     UserLevel::$keys['vip2'],
                    // ]);
                    // if ($second) {
                    //     $commission = $this->set->repeat_vip2_second;
                    //
                    //     $commission *= $item['quantity'];
                    //     $this->saveCommission($second->id, $this->order->user_id, $this->order->id, $commission, $award[1][0], $award[1][1]);
                    //
                    //     // equal
                    //     $this->_equal($second, $item['quantity'], true);
                    // }

                }

            }
        }
    }

    private function _diff($diff_key)
    {
        $order_items = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->all();

        $sum = 0;
        foreach ($order_items as $item) {
            // 这里可以不用商品原价, order_item中是折后价
            $product = SetProductCommission::findOne(['product_id' => $item->product_id])->toArray();
            // var_dump($product);exit;
            $sum += ($item['price'] - $product[$diff_key]) * $item['quantity'];
        }

        return $sum;
    }

    public function diff()
    {
        $chain = Chain::getReferrerChain($this->order->user_id, [], true);

        $award_name = '复购差价';
        $award_type = 30;

        $diff_vip1 = 0;
        $diff_vip2 = 0;
        $diff_vip3 = 0;

        $has_vip1 = false;
        $has_vip2 = false;
        $has_vip3 = false;

        foreach ($chain as $user) {
            if ($user->level <= $this->user->level) {
                continue;
            }

            if ((!$has_vip1 && !$has_vip2 && !$has_vip3) && $user->level == UserLevel::$keys['vip1']) {
                $diff_vip1 = $this->_diff('diff_vip1');
                $this->saveCommission($user->id, $this->order->user_id, $this->order->id, $diff_vip1, $award_type, $award_name);
                $has_vip1 = true;
            }
            if ((!$has_vip2 && !$has_vip3) && $user->level == UserLevel::$keys['vip2']) {
                $diff_vip2 = $this->_diff('diff_vip2');
                $diff_vip2 -= $diff_vip1;
                $this->saveCommission($user->id, $this->order->user_id, $this->order->id, $diff_vip2, $award_type, $award_name);
                $has_vip2 = true;
            }
            if (!$has_vip3 && $user->level == UserLevel::$keys['vip3']) {
                $diff_vip3 = $this->_diff('diff_vip3');
                $diff_vip3 -= $diff_vip2 + $diff_vip1;
                $this->saveCommission($user->id, $this->order->user_id, $this->order->id, $diff_vip3, $award_type, $award_name);
                $has_svip1 = true;
                break;
            }
        }
    }

    protected function _income($user_id, $amount, $more = '')
    {
        $type = 13;
        $name = '收益' . $more;

        $r1 = Chain::getReferrerChain($user_id, [UserLevel::$keys['vip3']], true);
        if ($r1) {
            $r1 = $r1[0];

            $c = $amount * $this->set->vip3_1 / 100;
            $this->saveCommission($r1->id, $this->order->user_id, $this->order->id, $c, $type, $name);

            // second
            $r2 = Chain::getReferrerChain($r1->id, [UserLevel::$keys['vip3']], true);
            if ($r2) {
                $r2 = $r2[0];

                $c = $amount * $this->set->vip3_2 / 100;
                $this->saveCommission($r2->id, $this->order->user_id, $this->order->id, $c, $type, $name);
            }
        }
    }

    // 获取真正拿间推奖的人(出局处理)
    protected function getIndirect($user_id)
    {
        $the_referrer = Chain::getReferrer($user_id, true);
        if (!$the_referrer) {
            return null;
        }

        // if ($the_referrer->level == UserLevel::$keys['vip2']) {
        if ($the_referrer->level == UserLevel::$keys['vip2'] || $the_referrer->level == UserLevel::$keys['vip3']) {
            // 判断是否属于前2个直推
            $children = Chain::getChildrenSort($the_referrer->id, ['id']);

            if (count($children) > 2) {
                $children = [$children[0], $children[1]];
                $in = in_array($user_id, $children);
                if (!$in) {
                    return $the_referrer;
                } else {
                    return $this->getIndirect($the_referrer->id);
                }
            } else {
                return $this->getIndirect($the_referrer->id);
            }
        }

        return $this->getIndirect($the_referrer->id);

    }

}